<!-- 代码已包含 CSS：使用 TailwindCSS , 安装 TailwindCSS 后方可看到布局样式效果 -->
<template>
  <div class="app-container">
    <div class="mx-auto">
      <div class="search-bar">
        <el-form :inline="true">
          <el-form-item label="设备型号或名称">
            <el-input
              v-noSpace
              v-model="queryParams.param.code"
              placeholder="请输入设备型号或名称"
              class="!w-[192px]"
              clearable
              @keyup.enter="getInfo()"
            ></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="getInfo()">查询</el-button>
          </el-form-item>
        </el-form>
      </div>

      <el-collapse v-model="activeNames" accordion>
        <el-collapse-item v-for="(item, index) in tabData" :name="index">
          <template #title>
            <div class="flex items-center justify-between flex-1 pr-4">
              <div class="flex items-center">
                <el-icon class="mr-2 text-blue-600"><Monitor /></el-icon>
                <div>
                  <span class="mr-2 text-lg font-medium">{{ item.name }}</span>
                  <span class="text-gray-500">{{ item.code }}</span>
                </div>
              </div>
              <span :class="item.status == 1 ? 'text-green-500' : 'text-red-500'">
                {{ item.status == 1 ? "运行中" : "已停止" }}
              </span>
            </div>
          </template>
          <div class="grid grid-cols-2 gap-x-8 gap-y-4 p-4">
            <div
              v-for="(items, index) in item.attributes"
              :key="index"
              class="grid grid-cols-[180px_1fr] items-center"
            >
              <span class="text-gray-600">{{ items.attrName }}：</span>
              {{
                items.attrCode == "MANUFACTURER"
                  ? items.attrValue == 1
                    ? "运行中"
                    : "已停止"
                  : items.attrValue
              }}
            </div>
          </div>
        </el-collapse-item>
      </el-collapse>
    </div>
    <pagination
      v-if="total > 0"
      v-model:total="total"
      v-model:page="queryParams.param.pageNum"
      v-model:limit="queryParams.param.pageSize"
      @pagination="getInfo"
    />
  </div>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import { Search, Setting, Monitor } from "@element-plus/icons-vue";
import router from "@/router";
import request from "@/utils/request";
import { getToken } from "@/utils/auth";
import equipmentManagementAPI, { Inquire } from "@/api/equipmentManagement/equipmentManagement";
const total = ref(0);
const activeNames = ref("1");
const tabData = ref();
const handleSizeChange = (val: number) => {
  console.log(`每页 ${val} 条`);

  getInfo();
};
const handleCurrentChange = (val: number) => {
  console.log(`当前页: ${val}`);
  getInfo();
};
let queryParams = ref({
  type: "ping", //ping
  param: {
    pageNum: 1,
    pageSize: 10,
    code: "",
  },
});
const startHealthCheck = () => {
  healthCheckInterval = setInterval(async () => {
    //发送一个请求，如果是token问题。直接退出到登录，否则继续重连
    //原生请求xml

    request
      .get("/core/messageRecord/unreadMessage")
      .then((res) => {
        console.log(res, "websocket健康检查响应状态码：");

        clearInterval(healthCheckInterval);
        connectWebSocket(); // 后端恢复，重启 WebSocket
      })
      .catch(() => {});
  }, 300000); // 每5分钟执行一次
};

//设置最大重连次数
const maxReconnectAttempts = 1;
let reconnectAttempts = ref(0);
let healthCheckInterval: NodeJS.Timeout; // 健康检查定时器
let pingInterval: NodeJS.Timeout; //发送ping定时器
let reconnectTimeout: NodeJS.Timeout; // 重连定时器
const reconnect = () => {
  if (reconnectAttempts.value <= maxReconnectAttempts) {
    reconnectTimeout = setTimeout(() => {
      reconnect();
      reconnectAttempts.value++;
      console.log("尝试重连", `重连次数${reconnectAttempts.value}`);
    }, 5000);
  } else {
    startHealthCheck(); // 开启健康检查
    console.error("达到最大重连次数，停止重连。");
  }
};
const websocketPoint = import.meta.env.VITE_APP_WS_ENDPOINT;
const ws = ref<WebSocket | null>(null);
const connectWebSocket = async () => {
  try {
    await request.get("/core/messageRecord/unreadMessage");
    ws.value = new WebSocket(`${websocketPoint}/eqptList?token=${getToken()}`);
    // ws.value = new WebSocket("ws://192.168.10.168:8081/core/ws/messageNotice?token=" + "123");
    ws.value.onopen = () => {
      console.log("WebSocket已连接");
      pingInterval = setInterval(() => {
        sendWebSocket("ping");
      }, 300000);
      sendWebSocket("ping");
    };

    ws.value.onmessage = async (event) => {
      const res = JSON.parse(event.data);
      if (res.type == "getData") {
        total.value = res.result.data.total;
        tabData.value = res.result.data?.list;
      }
      if (res.type == "unLogin") {
        return router.push("/login");
      }
    };
    ws.value.onclose = (event) => {
      console.log("断开了", event);
      ws.value = null;
      reconnect();
    };
    ws.value.onerror = (event) => {
      ws.value = null;
      console.log("WebSocket连接失败");
    };
  } catch (error) {
    startHealthCheck();
  }
};

// 定时发送消息
const sendWebSocket = (message: any) => {
  //ping = 回pong （如果没回则断开 300秒内不发ping消息也会断开）
  // close = 关闭
  // read  =  需多传一个messageId,成功处理 type=success  失败 type=error
  //已读将消息从sessionStorage列表中移除

  ws.value?.send(JSON.stringify(message));
};

function getInfo() {
  console.log(queryParams);
  // 连接打开后可以发送消息
  sendWebSocket(queryParams.value);
  // socket.value?.send(JSON.stringify(queryParams.value));
}
onMounted(() => {
  connectWebSocket();
});

onBeforeUnmount(() => {
  clearInterval(healthCheckInterval);
  clearInterval(pingInterval);
  clearTimeout(reconnectTimeout);
  // 组件卸载时关闭 WebSocket 连接
  queryParams.value.type = "close";
  sendWebSocket(queryParams.value);
  if (ws.value) {
    ws.value.close();
    ws.value.onclose = () => {
      console.log("WebSocket断开");
      ws.value = null;
    };
  }
});
</script>
<style scoped>
.el-input :deep(.el-input__wrapper) {
  box-shadow: 0 0 0 1px #e5e7eb;
}

.el-input :deep(.el-input__wrapper.is-focus) {
  box-shadow: 0 0 0 1px #409eff;
}

.el-select :deep(.el-input__wrapper) {
  box-shadow: 0 0 0 1px #e5e7eb;
}

.el-select :deep(.el-input__wrapper.is-focus) {
  box-shadow: 0 0 0 1px #409eff;
}

:deep(.el-collapse-item__header) {
  padding: 16px;
}

:deep(.el-collapse-item__content) {
  padding: 0;
}
</style>
